home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / tjgold.zip / INSTALL.001 / DFBTREUT.PAS < prev    next >
Pascal/Delphi Source File  |  1995-07-19  |  47KB  |  1,222 lines

  1. {--------------------------------------------------------------------------}
  2. {                Product: TechnoJock's Turbo Toolkit                       }
  3. {                Version: GOLD                                             }
  4. {                Build:   1.01                                             }
  5. {                                                                          }
  6. {  The index routines used in TTT Gold were developed by Dean Farwell II   }
  7. {  and are an adaptation of his excellent TBTREE database tools.           }
  8. {                                                                          }
  9. {                   Copyright 1988-1994 Dean Farwell II                    }
  10. {        Portions Copyright 1986-1995  TechnoJock Software, Inc.           }
  11. {                           All Rights Reserved                            }
  12. {                          Restricted by License                           }
  13. {--------------------------------------------------------------------------}
  14.  
  15.                      {********************************}
  16.                      {       Unit:   DFBTREUT         }
  17.                      {********************************}
  18.  
  19. unit DFBTreUt;
  20. {$I-}
  21. (*****************************************************************************)
  22. (*                                                                           *)
  23. (*                  N U M B E R   D E C L A R A T I O N S                    *)
  24. (*                                                                           *)
  25. (*****************************************************************************)
  26.  
  27. (* This unit has declarations for often used standard constants and types.
  28.    These are obviously not all inclusive and can be added to as desired.  It
  29.    also contains on routine.                                                *)
  30.  
  31.  
  32. (*////////////////////////// I N T E R F A C E //////////////////////////////*)
  33.  
  34. interface
  35.  
  36. const
  37.     MAXBYTE     = 255;
  38.     MAXSHORTINT = 127;
  39.     MAXWORD     = 65535;
  40.  
  41.     (* the following constants are used to reflect the number of bytes
  42.         required to hold the corresponding variable types.                   *)
  43.  
  44.     BYTESIZE      = 1;
  45.     SHORTINTSIZE  = 1;
  46.     INTEGERSIZE   = 2;
  47.     LONGINTSIZE   = 4;
  48.     WORDSIZE      = 2;
  49.     REALSIZE      = 6;
  50.     SINGLESIZE    = 4;
  51.     DOUBLESIZE    = 8;
  52.     EXTENDEDSIZE  = 10;
  53.     COMPSIZE      = 8;
  54.  
  55. type
  56.     PosByte       = 1 .. MAXBYTE;
  57.     PosShortInt   = 1 .. MAXSHORTINT;
  58.     PosInteger    = 1 .. MAXINT;
  59.     PosLongInt    = 1 .. MAXLONGINT;
  60.     PosWord       = 1 .. MAXWORD;
  61.  
  62.     Condition     = (EX,      (* Exists *)
  63.                      LT,      (* Less Than *)
  64.                      LE,      (* Less Than Or Equal To *)
  65.                      EQ,      (* Equal To *)
  66.                      NE,      (* Not Equal To *)
  67.                      GE,      (* Greater Than Or Equal To *)
  68.                      GT);     (* Greater Than *)
  69.  
  70.     StringCondition = (ST,    (* String Starts With Substring *)
  71.                        CO,    (* String Contains Substring *)
  72.                        EN);   (* String Ends With Substring *)
  73.  
  74.     ValueType = (INVALIDVALUE,
  75.                  BYTEVALUE,
  76.                  SHORTINTVALUE,
  77.                  INTEGERVALUE,
  78.                  LONGINTVALUE,
  79.                  WORDVALUE,
  80.                  STRINGVALUE,
  81.                  REALVALUE,
  82.                  SINGLEVALUE,
  83.                  DOUBLEVALUE,
  84.                  EXTENDEDVALUE,
  85.                  COMPVALUE,
  86.                  BYTEARRAYVALUE);
  87.  
  88.     SizeType = 1 .. MAXBYTE + 1;
  89.  
  90.  
  91. type
  92.     FnString = String[79];      (* See FNSIZE definition above for an
  93.                                        example of a file name                *)
  94.  
  95. (* Record number types                                                       *)
  96.  
  97. const
  98.     RNSIZE = 4;
  99.  
  100. type
  101.     RecordNumber = 0 .. MAXLONGINT;               (* range of record numbers *)
  102.  
  103.     PrNumber = RecordNumber;   (* Physical Record Number within a file       *)
  104.     LrNumber = RecordNumber;   (* Logical Record Number within file          *)
  105.  
  106. const
  107.     PAGESIZE = 512;                  (* Number of bytes in a Physical Record *)
  108.  
  109. type
  110.     PageRange  = 1 .. PAGESIZE;    (* type used primarily for indexing a page
  111.                                       byte by byte.                          *)
  112.  
  113.     SinglePage = Array [PageRange] of Byte;    (* type used to hold one page *)
  114.  
  115.  
  116.  
  117. (* This routine will return the size needed to store a variable of the
  118.    given type.  This is true for all types except for STRINGVALUE and
  119.    BYTEARRAYVALUE.  For these two types, the size can vary from 1 to 256
  120.    so 1 is returned.                                                        *)
  121.  
  122. function GetSizeFromVType(vType : ValueType) : SizeType;
  123.  
  124.  
  125. type
  126.     HexArray = String[2];
  127.  
  128.  
  129. (* Finds the hex character for a given 4 bit value
  130.    for example - GetHexChar(11) = 'B'                                       *)
  131.  
  132. function GetHexChar(var x : Byte) : Char;
  133.  
  134.  
  135. (* This function returns the hex value for an associated 8 bit byte.  The value
  136.    is returned as a string of type HexArray (2 bytes)
  137.    for example - ByteToHex(255) = 'FF'                                      *)
  138.  
  139. function ByteToHex(x : Byte) : HexArray;
  140.  
  141. type
  142.     TimeArr = record
  143.         lsLongInt : LongInt;               (* least significant long integer *)
  144.         msLongInt : LongInt;                (* most significant long integer *)
  145.         end;
  146.  
  147.  
  148. type
  149.     Comparison = (LESSTHAN,EQUALTO,GREATERTHAN);
  150.  
  151.  
  152. (* This routine will compare two values and return the result of the comparison.
  153.    The result is of type Comparison and LESSTHAN, EQUALTO, or GREATERTHAN will
  154.    be returned.  The values compared must be of the same type.  Legal types are
  155.    those enumerated in the type ValueType.  The type of the values is passed in
  156.    as a parameter along with the values.
  157.  
  158.    note : the values must reside in a variable since a var parameter is used.
  159.    This is necessary since the address is needed to facilitate the use of this
  160.    routine with multiple types.                                              *)
  161.  
  162. function CompareValues(var paramValue1;
  163.                        var paramValue2;
  164.                        vType : ValueType) : Comparison;
  165.  
  166.  
  167. (* This routine will convert the given value to a string.  This can be used to
  168.    facilitate the printing of a value.                                       *)
  169.  
  170. function ConvertValueToString(var paramValue1;
  171.                               vType : ValueType) : String;
  172.  
  173.  
  174. (* This routine does two things that are important to understand when
  175.    using it.  It first increments the internal clock.  It then sets x to this
  176.    new "time".                                                               *)
  177.  
  178. procedure GetTime(var x : TimeArr);
  179.  
  180.  
  181. (* This function compares two time arrays.  LESSTHAN is returned if X is less
  182.    than Y (earlier).  GREATERTHAN is returned if X is greater than Y (later).
  183.    If they are equal then EQUALTO is returned                                *)
  184.  
  185. function CompareTime(var x : TimeArr;
  186.                      var y : TimeArr) : Comparison;
  187.  
  188.  
  189. (* This routine sets both long integer fields of a timeArr variable to the
  190.    maximum possible value (MAXLONGINT)                                       *)
  191.  
  192. procedure SetMaxTime(var x : TimeArr);
  193.  
  194.  
  195. (* the following type supports the byte handling routine(s)                  *)
  196.  
  197. type
  198.     BytePosition = 0 .. 7;
  199.     BitValue = 0 .. 1;
  200.  
  201.  
  202. (* This function will determine if a certain bit within a target byte is
  203.    toggled on (equal to 1).  The bit position is is the position within the
  204.    byte of the bit to be tested.  The least significant bit is 0 then most
  205.    significant bit is 7.  If the bit is 1 TRUE will be returned.  If the bit
  206.    is 0 FALSE will be returned.  Notice that the target byte can be of any
  207.    type.  in this way, the routine will handle any a bit byte.  In other
  208.    words a character could also be passed in.                                *)
  209.  
  210. (* Boolean functions return zero flag set and AL=0 for false,
  211.                             zero flag reset and AL=1 for true                *)
  212.  
  213. function BitOn(var targetByte;
  214.                bitNum : BytePosition ):boolean;
  215.  
  216. (*      pop cx                   ;bitNum
  217.         pop bx                   ;offset of targetByte
  218.         pop es                   ;segment of targetByte
  219.         mov al, byte ptr es:[bx] ;get the byte
  220.         shr al,cl                ;get desired bit
  221.                                  ;in rightmost position
  222.         and al,01                ;check for bit set                          *)
  223.  
  224.     INLINE($59/$5B/$07/$26/$8A/$07/$D2/$E8/$24/$01);
  225.  
  226.  
  227. (* This will set a given bit to a value of zero or one depending on what is
  228.    passed in as the last parameter.  See above for description of the other
  229.    parameters                                                                *)
  230.  
  231. procedure SetBit(var targetByte;
  232.                  bitNum : BytePosition;
  233.                  bit : BitValue );
  234.  
  235. (*      pop ax                  ;bit
  236.         pop cx                  ;bitNum
  237.         pop bx                  ;offset of targetByte
  238.         pop es                  ;segment of targetByte
  239.         mov ah,11111110b        ;mask to reset
  240.         rol ah,cl               ;get it in place
  241.         and byte ptr es:[bx],ah ;reset regardless
  242.         shl al,cl               ;mask to set/reset
  243.         or byte ptr es:[bx],al  ;make bit proper value                       *)
  244.  
  245.     INLINE($58/$59/$5B/$07/$B4/$FE/$D2/$C4/$26/$20/$27/$D2/$E0/$26/$08/$07);
  246.  
  247.  
  248.  
  249. type
  250.     ByteArrayRange = 0 .. MAXBYTE;
  251.  
  252.     ByteArray = Array [ByteArrayRange] of Byte;    (* This handy type is used
  253.                                                       to store a from 1 to
  254.                                                       255 bytes.  It is much
  255.                                                       a string in that the
  256.                                                       first element is the
  257.                                                       number of bytes in the
  258.                                                       array. All bytes after
  259.                                                       the significant number
  260.                                                       of bytes are not
  261.                                                       significant.  This is
  262.                                                       used for concatenated
  263.                                                       indexes                *)
  264.  
  265. type
  266.     PrintTextDevice = Text;
  267.     PrinterType = (GENERIC,EPSON,HP);
  268.     LinesPerInch = 1 .. 48;
  269.  
  270.  
  271. procedure SetPrinterType(p : PrinterType);
  272.  
  273. procedure FormFeed(var lst : PrintTextDevice);
  274.  
  275. procedure InitializePrinter(var lst : PrintTextDevice);
  276.  
  277. procedure SetCompressedMode(var lst : PrintTextDevice);
  278.  
  279. procedure CancelCompressedMode(var lst : PrintTextDevice);
  280.  
  281. procedure SetEmphasizedMode(var lst : PrintTextDevice);
  282.  
  283. procedure CancelEmphasizedMode(var lst : PrintTextDevice);
  284.  
  285. (* This works for HP printers only.  It will set the number of lines per inch
  286.    to the specified legal value.  The legal values are 1,2,3,4,6,12,24,48.
  287.    Other values will be ignored.                                             *)
  288.  
  289. procedure SetLinesPerInch(var lst : PrintTextDevice;
  290.                           n : LinesPerInch);
  291.  
  292.  
  293. const
  294.     MAXSTRINGLENGTH = 255;                     (* max characters in a string *)
  295.  
  296. type
  297.     StringLengthRange = 0 .. MAXSTRINGLENGTH;  (* range of number of
  298.                                                   characters in a string     *)
  299.  
  300.  
  301. (* Takes a string and adds up the integer value of each individual byte.
  302.    This total can be used to randomize the string for Hashing, etc.          *)
  303.  
  304. function TotalString(var str : String) : Word;
  305.  
  306.  
  307. (* This routine will move records for the given file down n records.  This
  308.    will free up n physical records for use.  The first record to be moved is
  309.    passed in firstRec and the last record to move is lastRec.  lastRec must be
  310.    the last physical record in the file.  firstRec and lastRec will be
  311.    returned with values updated to reflect where the records now reside.  The
  312.    new last record will be written to disk (forced) to ensure that all
  313.    physical records (from the beginning to the end of the file) will exist on
  314.    the disk.                                                                 *)
  315.  
  316. procedure MoveRecords(fName : FnString;
  317.                       var fId : File;          (* var for speed only *)
  318.                       var firstRec : PrNumber;
  319.                       var lastRec : PrNumber;
  320.                       n : PrNumber);
  321.  
  322.  
  323. procedure FetchFileParameters(var dFName : FnString;   (* var for speed only *)
  324.                               var fId : File;          (* var for speed only *)
  325.                               var pRec;
  326.                               size : PageRange);
  327.  
  328.  
  329. (* This procedure will copy the contents of pRec and save it to the zeroth
  330.    physical record in the data file.                                         *)
  331.  
  332.  
  333. procedure SaveFileParameters(var dFName : FnString;    (* var for speed only *)
  334.                              var fId : File;           (* var for speed only *)
  335.                              var pRec;
  336.                              size : PageRange);
  337.  
  338.  
  339. (* This routine will perform two important functions.  First, it will set the
  340.    bit corresponding to rNum to show that the record is used.  Second, it will
  341.    find the next available record number and will return that record number.
  342.    It may require the addition of one bitmap record to do that.  If this is
  343.    required, it will be performed automatically.                             *)
  344.  
  345. function FindNextAvailInBitmap(fName : FnString;
  346.                                var fId : File;         (* var for speed only *)
  347.                                firstBMRec : PrNumber;
  348.                                var lastBMRec : PrNumber;
  349.                                rNum : RecordNumber) : RecordNumber;
  350.  
  351.  
  352.  
  353.  
  354. (* This routine will set the bit associated with rNum in the file fName to
  355.    the desired value. It will calculate the correct bitmap record and read it
  356.    in, set the bit to the value specified by bit (the parameter of type
  357.    BitValue passed in) and store the bitmap record.                          *)
  358.  
  359. procedure SetBitInBitmap(fName : FnString;
  360.                          var fId : File;               (* var for speed only *)
  361.                          firstBMRec : PrNumber;
  362.                          rNum : RecordNumber;
  363.                          bit : BitValue);
  364.  
  365.  
  366. (* This routine will check to see if the bit associated with rNum in the file
  367.    fName is set or not.  The routine will return TRUE if the bit is set.     *)
  368.  
  369. function CheckBitInBitmap(fName : FnString;
  370.                           var fId : File;              (* var for speed only *)
  371.                           firstBMRec : PrNumber;
  372.                           rNum : RecordNumber) : Boolean;
  373.  
  374.  
  375. const
  376.     NOERROR = 0;
  377.  
  378. type
  379.     IOErrorCode = Integer;
  380.  
  381. var
  382.     bTreeErrorCode : IOErrorCode;
  383.  
  384. procedure SetBTreeError(errorCode : IOErrorCode);
  385.  
  386. function GetBTreeError : IOErrorCode;
  387.  
  388. function BTreeErrorOccurred : Boolean;
  389.  
  390.  
  391. (*///////////////////// I M P L E M E N T A T I O N /////////////////////////*)
  392.  
  393. implementation
  394.  
  395. uses
  396.     Dos,
  397.     DFPage;
  398.  
  399. (* This routine will return the size needed to store a variable of the
  400.    given type.  This is true for all types except for STRINGVALUE and
  401.    BYTEARRAYVALUE.  For these two types, the size can vary from 1 to 256
  402.    so 1 is returned.                                                        *)
  403.  
  404. function GetSizeFromVType(vType : Valuetype) : SizeType;
  405.  
  406.         begin
  407.         case vType of
  408.             BYTEVALUE       : GetSizeFromVType := BYTESIZE;
  409.             SHORTINTVALUE   : GetSizeFromVType := SHORTINTSIZE;
  410.             INTEGERVALUE    : GetSizeFromVType := INTEGERSIZE;
  411.             LONGINTVALUE    : GetSizeFromVType := LONGINTSIZE;
  412.             WORDVALUE       : GetSizeFromVType := WORDSIZE;
  413.             STRINGVALUE     : GetSizeFromVType := 1;
  414.             REALVALUE       : GetSizeFromVType := REALSIZE;
  415.             SINGLEVALUE     : GetSizeFromVType := SINGLESIZE;
  416.             DOUBLEVALUE     : GetSizeFromVType := DOUBLESIZE;
  417.             EXTENDEDVALUE   : GetSizeFromVType := EXTENDEDSIZE;
  418.             COMPVALUE       : GetSizeFromVType := COMPSIZE;
  419.             BYTEARRAYVALUE  : GetSizeFromVType := 1;
  420.             end;                                   (* end of case statement *)
  421.         end;                                    (* end of GetVSizeFromVType *)
  422.  
  423.  
  424.  
  425. (* Finds the hex character for a given 4 bit value
  426.    for example - GetHexChar(11) = 'B'                                       *)
  427.  
  428. function GetHexChar(var x : Byte) : Char;
  429.  
  430. var
  431.     result1 : Byte;
  432.     result2 : Char absolute result1;
  433.  
  434.     begin
  435.     if (x >= 0) and (x <=9) then
  436.         result1 := x + 48
  437.     else
  438.         result1 := x + 55;
  439.  
  440.     GetHexChar := result2;
  441.     end;                                        (* End of GetHexChar Routine *)
  442.  
  443.  
  444. (* This function returns the hex value for an associated 8 bit byte.  The value
  445.    is returned as a string of type HexArray (2 bytes)
  446.    for example - ByteToHex(255) = 'FF'                                      *)
  447.  
  448. Function ByteToHex(x : Byte) : HexArray;
  449.  
  450. var
  451.     low,
  452.     high : Byte;
  453.  
  454.     begin
  455.     high := x div 16;
  456.     low  := x mod 16;
  457.     ByteToHex := GetHexChar(high) + GetHexChar(low);
  458.     end;                                         (* End of ByteToHex Routine *)
  459.  
  460.  
  461. var
  462.     clock : TimeArr;
  463.  
  464. (* This routine does two things that are important to understand when
  465.    using it.  It first increments the internal clock.  It then sets x to this
  466.    new "time".                                                               *)
  467.  
  468. procedure GetTime(var x : TimeArr);
  469.  
  470.     begin
  471.     if clock.lsLongInt = MAXLONGINT then
  472.         begin
  473.         clock.lsLongInt := 0;
  474.         Inc(clock.msLongInt);
  475.         end
  476.     else
  477.         begin
  478.         Inc(clock.lsLongInt);
  479.         end;
  480.     x := clock;
  481.     end;                                           (* end of GetTime routine *)
  482.  
  483.  
  484. (* This function compares two time arrays.  LESSTHAN is returned if X is less
  485.    than Y (earlier).  GREATERTHAN is returned if X is greater than Y (later).
  486.    If they are equal then EQUALTO is returned                                *)
  487.  
  488. function CompareTime(var x : TimeArr;
  489.                      var y : TimeArr) : Comparison;
  490.  
  491.     begin
  492.     if x.msLongInt = y.msLongInt then
  493.         begin
  494.         if x.lsLongInt < y.lsLongInt then
  495.             begin
  496.             CompareTime := LESSTHAN;
  497.             Exit;
  498.             end
  499.         else
  500.             begin
  501.             if x.lsLongInt = y.lsLongInt then
  502.                 begin
  503.                 CompareTime := EQUALTO;
  504.                 Exit
  505.                 end
  506.             else
  507.                 begin
  508.                 CompareTime := GREATERTHAN;
  509.                 Exit;
  510.                 end;
  511.             end;
  512.         end
  513.     else
  514.         begin
  515.         if x.msLongInt < y.msLongInt then
  516.             begin
  517.             CompareTime := LESSTHAN;
  518.             Exit;
  519.             end
  520.         else
  521.             begin
  522.             if x.msLongInt = y.msLongInt then
  523.                 begin
  524.                 CompareTime := EQUALTO;
  525.                 Exit;
  526.                 end
  527.             else
  528.                 begin
  529.                 CompareTime := GREATERTHAN;
  530.                 Exit;
  531.                 end;
  532.             end;
  533.         end;
  534.     end;                                       (* end of CompareTime routine *)
  535.  
  536.  
  537. (* This routine will print the two long integers that make up x (of type
  538.    TimeArr)                                                                  *)
  539.  
  540. procedure PrintTime(x : TimeArr);
  541.  
  542.     begin
  543.     Writeln('Most Significant Long Integer = ',x.msLongInt);
  544.     Writeln('Least Significant Long Integer = ',x.lsLongInt);
  545.     end;                                         (* end of PrintTime routine *)
  546.  
  547.  
  548. (* This routine sets both long integer fields of a timeArr variable to the
  549.    maximum possible value (MAXLONGINT)                                       *)
  550.  
  551. procedure SetMaxTime(var x : TimeArr);
  552.  
  553.     begin
  554.     x.lsLongInt := MAXLONGINT;
  555.     x.msLongInt := MAXLONGINT;
  556.     end;                                        (* end of SetMaxTime routine *)
  557.  
  558.  
  559.  
  560. (* This routine will compare two values and return the result of the comparison.
  561.    The result is of type Comparison and LESSTHAN, EQUALTO, or GREATERTHAN will
  562.    be returned.  The values compared must be of the same type.  Legal types are
  563.    those enumerated in the type ValueType.  The type of the values is passed in
  564.    as a parameter along with the values.
  565.  
  566.    note : the values must reside in a variable since a var parameter is used.
  567.    This is necessary since the address is needed to facilitate the use of this
  568.    routine with multiple types.                                              *)
  569.  
  570. function CompareValues(var paramValue1;
  571.                        var paramValue2;
  572.                        vType : ValueType) : Comparison;
  573.  
  574. var
  575.     byteValue1        : Byte     absolute paramValue1;
  576.     byteValue2        : Byte     absolute paramValue2;
  577.     shortIntValue1    : ShortInt absolute paramValue1;
  578.     shortIntValue2    : ShortInt absolute paramValue2;
  579.     integerValue1     : Integer  absolute paramValue1;
  580.     integerValue2     : Integer  absolute paramValue2;
  581.     longIntValue1     : LongInt  absolute paramValue1;
  582.     longIntValue2     : LongInt  absolute paramValue2;
  583.     wordValue1        : Word     absolute paramValue1;
  584.     wordValue2        : Word     absolute paramValue2;
  585.     stringValue1      : String   absolute paramValue1;
  586.     stringValue2      : String   absolute paramValue2;
  587.     realValue1        : Real     absolute paramValue1;
  588.     realValue2        : Real     absolute paramValue2;
  589.     singleValue1      : Single   absolute paramValue1;
  590.     singleValue2      : Single   absolute paramValue2;
  591.     doubleValue1      : Double   absolute paramValue1;
  592.     doubleValue2      : Double   absolute paramValue2;
  593.     extendedValue1    : Extended absolute paramValue1;
  594.     extendedValue2    : Extended absolute paramValue2;
  595.     compValue1        : Comp     absolute paramValue1;
  596.     compValue2        : Comp     absolute paramValue2;
  597.     byteArrayValue1   : ByteArray absolute paramValue1;
  598.     byteArrayValue2   : ByteArray absolute paramValue2;
  599.  
  600.     cnt : ByteArrayRange;
  601.  
  602.     begin
  603.     case vType of
  604.         BYTEVALUE :
  605.             begin
  606.             if byteValue1 < byteValue2 then CompareValues := LESSTHAN
  607.             else if byteValue1 = byteValue2 then CompareValues := EQUALTO
  608.             else CompareValues := GREATERTHAN;
  609.             end;
  610.         SHORTINTVALUE :
  611.             begin
  612.             if shortIntValue1 < shortIntValue2 then CompareValues := LESSTHAN
  613.             else if shortIntValue1 = shortIntValue2 then CompareValues :=EQUALTO
  614.             else CompareValues := GREATERTHAN;
  615.             end;
  616.         INTEGERVALUE :
  617.             begin
  618.             if integerValue1 < integerValue2 then CompareValues := LESSTHAN
  619.             else if integerValue1 = integerValue2 then CompareValues := EQUALTO
  620.             else CompareValues := GREATERTHAN;
  621.             end;
  622.         LONGINTVALUE :
  623.             begin
  624.             if longIntValue1 < longIntValue2 then CompareValues := LESSTHAN
  625.             else if longIntValue1 = longIntValue2 then CompareValues := EQUALTO
  626.             else CompareValues := GREATERTHAN;
  627.             end;
  628.         WORDVALUE :
  629.             begin
  630.             if wordValue1 < wordValue2 then CompareValues := LESSTHAN
  631.             else if wordValue1 = wordValue2 then CompareValues := EQUALTO
  632.             else CompareValues := GREATERTHAN;
  633.             end;
  634.         STRINGVALUE:
  635.             begin
  636.             if stringValue1 < stringValue2 then CompareValues := LESSTHAN
  637.             else if stringValue1 = stringValue2 then CompareValues := EQUALTO
  638.             else CompareValues := GREATERTHAN;
  639.             end;
  640.         REALVALUE :
  641.             begin
  642.             if realValue1 < realValue2 then CompareValues := LESSTHAN
  643.             else if realValue1 = realValue2 then CompareValues := EQUALTO
  644.             else CompareValues := GREATERTHAN;
  645.             end;
  646. (*   The following types are only for 8087 - and are compiled only if the unit
  647.      is compiled using {$N+}                                                 *)
  648.  
  649. {$IFOPT N+}
  650.         SINGLEVALUE :
  651.             begin
  652.             if singleValue1 < singleValue2 then CompareValues := LESSTHAN
  653.             else if singleValue1 = singleValue2 then CompareValues := EQUALTO
  654.             else CompareValues := GREATERTHAN;
  655.             end;
  656.         DOUBLEVALUE :
  657.             begin
  658.             if doubleValue1 < doubleValue2 then CompareValues := LESSTHAN
  659.             else if doubleValue1 = doubleValue2 then CompareValues := EQUALTO
  660.             else CompareValues := GREATERTHAN;
  661.             end;
  662.         EXTENDEDVALUE :
  663.             begin
  664.             if extendedValue1 < extendedValue2 then CompareValues := LESSTHAN
  665.             else if extendedValue1 = extendedValue2 then CompareValues :=EQUALTO
  666.             else CompareValues := GREATERTHAN;
  667.             end;
  668.         COMPVALUE :
  669.             begin
  670.             if compValue1 < compValue2 then CompareValues := LESSTHAN
  671.             else if compValue1 = compValue2 then CompareValues := EQUALTO
  672.             else CompareValues := GREATERTHAN;
  673.             end;
  674. {$ENDIF}
  675.  
  676.         (* the following type was added in version 1.4 *)
  677.         BYTEARRAYVALUE :
  678.             begin
  679.             cnt := 1;
  680.             while TRUE do
  681.                 begin
  682.                 if byteArrayValue1[0] < cnt then
  683.                     begin
  684.                     if byteArrayValue2[0] < cnt then
  685.                         begin
  686.                         CompareValues := EQUALTO;
  687.                         end
  688.                     else
  689.                         begin
  690.                         CompareValues := LESSTHAN;
  691.                         end;
  692.                     Exit;
  693.                     end;
  694.                 if byteArrayValue2[0] < cnt then
  695.                     begin
  696.                     CompareValues := GREATERTHAN;
  697.                     Exit;
  698.                     end;
  699.                 if byteArrayValue1[cnt] < byteArrayValue2[cnt] then
  700.                     begin
  701.                     CompareValues := LESSTHAN;
  702.                     Exit;
  703.                     end;
  704.                 if byteArrayValue1[cnt] > byteArrayvalue2[cnt] then
  705.                     begin
  706.                     CompareValues := GREATERTHAN;
  707.                     Exit;
  708.                     end;
  709.                 if cnt = MAXBYTE then
  710.                     begin
  711.                     CompareValues := EQUALTO;
  712.                     Exit;
  713.                     end;
  714.                 Inc(cnt);
  715.                 end;
  716.             end;
  717.       end;                                        (* end of case statement *)
  718.     end;                                     (* end of CompareValues routine *)
  719.  
  720.  
  721. (* This routine will convert the given value to a string.  This can be used to
  722.    facilitate the printing of a value.                                       *)
  723.  
  724. function ConvertValueToString(var paramValue1;
  725.                               vType : ValueType) : String;
  726.  
  727. var
  728.     byteValue1        : Byte     absolute paramValue1;
  729.     shortIntValue1    : ShortInt absolute paramValue1;
  730.     integerValue1     : Integer  absolute paramValue1;
  731.     longIntValue1     : LongInt  absolute paramValue1;
  732.     wordValue1        : Word     absolute paramValue1;
  733.     stringValue1      : String   absolute paramValue1;
  734.     realValue1        : Real     absolute paramValue1;
  735.     singleValue1      : Single   absolute paramValue1;
  736.     doubleValue1      : Double   absolute paramValue1;
  737.     extendedValue1    : Extended absolute paramValue1;
  738.     compValue1        : Comp     absolute paramValue1;
  739.     byteArrayValue1   : ByteArray absolute paramValue1;
  740.  
  741.     s : String;
  742.  
  743.     begin
  744.     case vType of
  745.         BYTEVALUE      : Str(byteValue1,s);
  746.         SHORTINTVALUE  : Str(shortIntValue1,s);
  747.         INTEGERVALUE   : Str(integerValue1,s);
  748.         LONGINTVALUE   : Str(longIntValue1,s);
  749.         WORDVALUE      : Str(wordValue1,s);
  750.         STRINGVALUE    : s := String(stringValue1);
  751.         REALVALUE      : Str(realValue1,s);
  752. (*   The following types are only for 8087 - and are compiled only if the unit
  753.      is compiled using {$N+}                                                 *)
  754.  
  755. {$IFOPT N+}
  756.         SINGLEVALUE    : Str(singleValue1,s);
  757.         DOUBLEVALUE    : Str(doubleValue1,s);
  758.         EXTENDEDVALUE  : Str(extendedValue1,s);
  759.         COMPVALUE      : Str(compValue1,s);
  760. {$ENDIF}
  761.  
  762.         (* the following type was added in version 1.4 *)
  763.         BYTEARRAYVALUE : Move(byteArrayValue1,s,byteArrayValue1[0]);
  764.         end;                                        (* end of case statement *)
  765.     ConvertValueToString := s;
  766.     end;                              (* end of ConvertValueToString routine *)
  767.  
  768.  
  769. const                             (* The following are the printer constants *)
  770.     GENERICFORMFEED = #12;
  771.  
  772.     HPINIT          = #27'E'#27'(s0p12h10v0s0b3T';
  773.     HPFORMFEED      = #12;
  774.     HPITALIC        = #27'(s1S';
  775.     HPNOITALIC      = #27'(s0S';
  776.     HPBOLD          = #27'(s3B';
  777.     HPNOBOLD        = #27'(s0B';
  778.     HPCOMPRESSED    = #27'E'#27'(s0p16.66h8.5v0s0b0T';
  779.     HPCNXCOMPRESSED = #27'(s0p12h10v0s0b3T';
  780.  
  781.     EPSONINIT          = #0;            (* to use replace with correct codes *)
  782.     EPSONFORMFEED      = #12;
  783.     EPSONITALIC        = #0;            (* to use replace with correct codes *)
  784.     EPSONNOITALIC      = #0;            (* to use replace with correct codes *)
  785.     EPSONBOLD          = #0;            (* to use replace with correct codes *)
  786.     EPSONNOBOLD        = #0;            (* to use replace with correct codes *)
  787.     EPSONCOMPRESSED    = #0;            (* to use replace with correct codes *)
  788.     EPSONCNXCOMPRESSED = #0;            (* to use replace with correct codes *)
  789.  
  790.  
  791. type
  792.     PrinterCodes = (PRINITIALIZE,
  793.                     PRFORMFEED,
  794.                     PRITALIC,PRNOITALIC,
  795.                     PRBOLD,PRNOBOLD,
  796.                     PRULINE,PRNOULINE,
  797.                     PRCOMPRESSED,PRCNXCOMPRESSED);
  798.  
  799.     PrinterCodeString = String;
  800.     PrinterCodeArray = array [PrinterCodes] of PrinterCodeString;
  801.  
  802. var
  803.     pCodeArray : PrinterCodeArray;
  804.     prType : PrinterType;
  805.  
  806. procedure SetPrinterType(p : PrinterType);
  807.  
  808.     begin
  809.     case p of
  810.         GENERIC:
  811.             begin
  812.             pCodeArray[PRFORMFEED] := GENERICFORMFEED;
  813.             end;
  814.         HP:
  815.             begin
  816.             pCodeArray[PRINITIALIZE] := HPINIT;
  817.             pCodeArray[PRFORMFEED] := HPFORMFEED;
  818.             pCodeArray[PRITALIC] := HPITALIC;
  819.             pCodeArray[PRNOITALIC] := HPNOITALIC;
  820.             pCodeArray[PRBOLD] := HPBOLD;
  821.             pCodeArray[PRNOBOLD] := HPNOBOLD;
  822.             pCodeArray[PRBOLD] := HPBOLD;
  823.             pCodeArray[PRCOMPRESSED] := HPCOMPRESSED;
  824.             pCodeArray[PRCNXCOMPRESSED] := HPCNXCOMPRESSED;
  825.             end;
  826.         EPSON:
  827.             begin
  828.             pCodeArray[PRINITIALIZE] := EPSONINIT;
  829.             pCodeArray[PRFORMFEED] := EPSONFORMFEED;
  830.             pCodeArray[PRITALIC] := EPSONITALIC;
  831.             pCodeArray[PRNOITALIC] := EPSONNOITALIC;
  832.             pCodeArray[PRBOLD] := EPSONBOLD;
  833.             pCodeArray[PRNOBOLD] := EPSONNOBOLD;
  834.             pCodeArray[PRBOLD] := EPSONBOLD;
  835.             pCodeArray[PRCOMPRESSED] := EPSONCOMPRESSED;
  836.             pCodeArray[PRCNXCOMPRESSED] := EPSONCNXCOMPRESSED;
  837.             end;
  838.         end;
  839.     end;                                   (* end of SetPrinterCodes routine *)
  840.  
  841.  
  842. procedure FormFeed(var lst : PrintTextDevice);
  843.  
  844.     begin
  845.     Write(lst,pCodeArray[PRFORMFEED]);
  846.     end;
  847.  
  848.  
  849. procedure InitializePrinter(var lst : PrintTextDevice);
  850.  
  851.     begin
  852.     Write(lst,pCodeArray[PRINITIALIZE]);
  853.     end;
  854.  
  855. procedure SetCompressedMode(var lst : PrintTextDevice);
  856.  
  857.     begin
  858.     Write(lst,pCodeArray[PRCOMPRESSED]);
  859.     end;
  860.  
  861. procedure CancelCompressedMode(var lst : PrintTextDevice);
  862.  
  863.     begin
  864.     Write(lst,pCodeArray[PRCNXCOMPRESSED]);
  865.     end;
  866.  
  867. procedure SetEmphasizedMode(var lst : PrintTextDevice);
  868.  
  869.     begin
  870.     Write(lst,pCodeArray[PRBOLD]);
  871.     end;
  872.  
  873. procedure CancelEmphasizedMode(var lst : PrintTextDevice);
  874.  
  875.     begin
  876.     Write(lst,pCodeArray[PRNOBOLD]);
  877.     end;
  878.  
  879. (* This works for HP printers only.  It will set the number of lines per inch
  880.    to the specified legal value.  The legal values are 1,2,3,4,6,12,24,48.
  881.    Other values will be ignored.                                             *)
  882.  
  883. procedure SetLinesPerInch(var lst : PrintTextDevice;
  884.                           n : LinesPerInch);
  885.  
  886.     begin
  887.     case n of
  888.         1:   write(lst,#27,#038,#108,#49,#68);
  889.         2:   write(lst,#27,#038,#108,#50,#68);
  890.         3:   write(lst,#27,#038,#108,#51,#68);
  891.         4:   write(lst,#27,#038,#108,#52,#68);
  892.         6:   write(lst,#27,#038,#108,#54,#68);
  893.         8:   write(lst,#27,#038,#108,#56,#68);
  894.         12:  write(lst,#27,#038,#108,#49,#50,#68);
  895.         16:  write(lst,#27,#038,#108,#49,#54,#68);
  896.         24:  write(lst,#27,#038,#108,#50,#52,#68);
  897.         48:  write(lst,#27,#038,#108,#52,#56,#68);
  898.         end;
  899.     end;
  900.  
  901.  
  902. (* Takes a string and adds up the integer value of each individual byte.
  903.    This total can be used to randomize the string for Hashing, etc.          *)
  904.  
  905. function TotalString(var str : String ) : Word;
  906.  
  907.     begin
  908.     Inline($31/$C0/      (*  xor   ax,ax              ; zero out accumulator *)
  909.            $31/$C9/      (*  xor   cx,cx              ; zero out counter     *)
  910.            $C4/$BE/>STR/ (*  les   di, >str[bp]       ; load pointer to str  *)
  911.            $26/$8A/$0D/  (* es: mov   cl,[di]         ;                      *)
  912.                          (* CountLoop:                                       *)
  913.            $47/          (*  inc   di                 ; next char            *)
  914.            $26/$02/$05/  (* es: add   al,[di]         ; add value of char    *)
  915.            $80/$D4/$00/  (*  adc   ah,0               ; add carry
  916.                                                         if required          *)
  917.            $E2/$F7/      (*  loop  CountLoop          ; get next char        *)
  918.            $89/$46/$FE); (*  mov   [bp-02],ax         ; put total on stack   *)
  919.  
  920.     end;                                      (* end of TotalString routine  *)
  921.  
  922.  
  923. (* This routine converts a string from ASCIIZ (null delimined) to Turbo Pascal
  924.    format                                                                    *)
  925.  
  926. function Asciiz2Str(var aStr) : string;
  927.  
  928. var str : String;
  929.     ctr : Word;
  930.     az: Array[1 .. MAXSTRINGLENGTH] of Char absolute aStr;
  931.  
  932.     begin
  933.     ctr := 1;
  934. {$B-}                           (* short circuit boolean evaluation required *)
  935.     while (ctr <= MAXSTRINGLENGTH) and (az[ctr] <> #0) do
  936.         begin
  937.         str[ctr] := az[ctr];
  938.         Inc(ctr);
  939.         end;
  940.     str[0] := Chr(ctr-1);
  941.     Asciiz2Str := str;
  942.     end;                                         (* end of Ascii2Str routine *)
  943.  
  944.  
  945. (* This routine will move records for the given file down n records.  This
  946.    will free up n physical records for use.  The first record to be moved is
  947.    passed in firstRec and the last record to move is lastRec.  lastRec must be
  948.    the last physical record in the file.  firstRec and lastRec will be
  949.    returned with values updated to reflect where the records now reside.  The
  950.    new last record will be written to disk (forced) to ensure that all
  951.    physical records (from the beginning to the end of the file) will exist on
  952.    the disk.                                                                 *)
  953.  
  954. procedure MoveRecords(fName : FnString;
  955.                       var fId : File;          (* var for speed only *)
  956.                       var firstRec : PrNumber;
  957.                       var lastRec : PrNumber;
  958.                       n : PrNumber);
  959.  
  960. var
  961.     zeroPage,
  962.     page : SinglePage;
  963.     cnt : PrNumber;
  964.  
  965.     begin
  966.     FillChar(zeroPage,PAGESIZE,0);                      (* zero out old page *)
  967.     for cnt := lastRec downto firstRec do
  968.         begin
  969.         FetchPage(fName,fId,cnt,page);
  970.         if BTreeErrorOccurred then Exit;
  971.         if cnt = lastRec then
  972.             begin             (* this is needed to force the physical file to
  973.                                  be extended, thus ensuring that all physical
  974.                                  records from the beginning to the new end of
  975.                                  the file will exist                        *)
  976.             StorePage(fName,fId,cnt + n,page);
  977.             if BTreeErrorOccurred then Exit;
  978.             end
  979.         else
  980.             begin
  981.             StorePage(fName,fId,cnt + n,page);
  982.             if BTreeErrorOccurred then Exit;
  983.             end;
  984.         StorePage(fName,fId,cnt,zeroPage); (* store empty page in old place *)
  985.         if BTreeErrorOccurred then Exit;
  986.         end;
  987.     Inc(firstRec,n);
  988.     Inc(lastRec,n);
  989.     end;                                       (* end of MoveRecords routine *)
  990.  
  991.  
  992. (* This routine will calculate the bit location for the given record
  993.    number (rNum).  firstBMRec is needed as the starting location.  The
  994.    location is returned in prNum, byteNum and bitNum.  The routine does not
  995.    affect the bitmaps themselves.                                            *)
  996.  
  997. procedure CalculateBitmapBitLocation(firstBMRec : PrNumber;
  998.                                      rNum : RecordNumber;
  999.                                      var prNum : PrNumber;
  1000.                                      var byteNum : PageRange;
  1001.                                      var bitNum : BytePosition);
  1002.  
  1003.     begin
  1004.     prNum := ((rNum - 1) Div (8 * PAGESIZE)) + firstBMRec;
  1005.     byteNum := (((rNum - 1) Mod (8 * PAGESIZE)) Div 8) + 1;
  1006.     bitNum := (rNum - 1) Mod 8;
  1007.     bitNum := (bitNum Xor 7) And 7;    (* this will yield the correct bit
  1008.                                           position within the byte. This is
  1009.                                           necessary because bit 7 (most
  1010.                                           significant) in the byte is the
  1011.                                           existence bit for the first record
  1012.                                           not the eighth *)
  1013.     end;                        (* end of CalculateBitmapBitLocation routine *)
  1014.  
  1015.  
  1016. (* This procedure will read the zeroth physical record from the given file and
  1017.    return the number of bytes requested in the variable pRec.                *)
  1018.  
  1019. procedure FetchFileParameters(var dFName : FnString;   (* var for speed only *)
  1020.                               var fId : File;          (* var for speed only *)
  1021.                               var pRec;
  1022.                               size : PageRange);
  1023.  
  1024. var
  1025.     page : SinglePage;
  1026.  
  1027.     begin
  1028.     FetchPage(dFName,fId,0,page);
  1029.     if BTreeErrorOccurred then Exit;
  1030.     Move(page,pRec,size);
  1031.     end;                            (* end of FetchFileParameters procedure *)
  1032.  
  1033.  
  1034. (* This procedure will copy the contents of pRec and save it to the zeroth
  1035.    physical record in the data file.                                         *)
  1036.  
  1037. procedure SaveFileParameters(var dFName : FnString;    (* var for speed only *)
  1038.                              var fId : File;           (* var for speed only *)
  1039.                              var pRec;
  1040.                              size : PageRange);
  1041.  
  1042. var
  1043.     page : SinglePage;
  1044.  
  1045.     begin
  1046.     FetchPage(dFName,fId,0,page);
  1047.     if BTreeErrorOccurred then Exit;
  1048.     Move(pRec,page,size);
  1049.     StorePage(dFName,fId,0,page);
  1050.     if BTreeErrorOccurred then Exit;
  1051.     end;                              (* end of SaveFileParameters procedure *)
  1052.  
  1053.  
  1054. (* This routine will calculate the physical record number corresponding to the
  1055.    given record number (rNum).  firstBMRec is needed as the starting
  1056.    location.                                                                 *)
  1057.  
  1058. function CalculateBitmapRecord(firstBMRec : PrNumber;
  1059.                                rNum : RecordNumber) : PrNumber;
  1060.  
  1061.     begin
  1062.     CalculateBitmapRecord := ((rNum - 1) Div (8 * PAGESIZE)) + firstBMRec;
  1063.     end;                          (* end of CalculateBitmapBitRecord routine *)
  1064.  
  1065.  
  1066. (* This routine will perform two important functions.  First, it will set the
  1067.    bit corresponding to rNum to show that the record is used.  Second, it will
  1068.    find the next available record number and will return that record number.
  1069.    It may require the addition of one bitmap record to do that.  If this is
  1070.    required, it will be performed automatically.                             *)
  1071.  
  1072. function FindNextAvailInBitmap(fName : FnString;
  1073.                                var fId : File;         (* var for speed only *)
  1074.                                firstBMRec : PrNumber;
  1075.                                var lastBMRec : PrNumber;
  1076.                                rNum : RecordNumber) : RecordNumber;
  1077.  
  1078. var
  1079.     page : SinglePage;                             (* copy of page in buffer *)
  1080.     prNum : PrNumber;
  1081.     byteNum : PageRange;                        (* byte position within page *)
  1082.     bitNum : BytePosition;                       (* bit position within byte *)
  1083.     done : Boolean;                                             (* byte loop *)
  1084.  
  1085.     begin
  1086.     CalculateBitmapBitLocation(firstBMRec,rNum,prNum,byteNum,bitNum);
  1087.     FetchPage(fName,fId,prNum,page);
  1088.     if BTreeErrorOccurred then Exit;
  1089.     SetBit(page[byteNum],bitNum,1);
  1090.     StorePage(fName,fId,prNum,page);
  1091.     if BTreeErrorOccurred then Exit;
  1092.     while TRUE do                                      (* BITMAP record loop *)
  1093.         begin
  1094.         done := FALSE;
  1095.         while not done do                                       (* byte loop *)
  1096.             begin
  1097.             if page[byteNum] <> MAXBYTE then
  1098.                               (* the check against MAXBYTE is for efficiency
  1099.                                since it will preclude checking individual
  1100.                                bits for a byte in which all bits are set
  1101.                                to one                                        *)
  1102.                 begin
  1103.                 bitNum := 7;
  1104.                 while TRUE do
  1105.                     begin                                        (* bit loop *)
  1106.                     if not BitOn(page[byteNum],bitNum) then
  1107.                         begin
  1108.                         FindNextAvailInBitmap := ((prNum - firstBMRec) *
  1109.                                                   PAGESIZE * 8) +
  1110.                                                  ((byteNum - 1) * 8) +
  1111.                                                  (8 - bitNum);
  1112.                         Exit;                     (* only way out of routine *)
  1113.                         end
  1114.                     else
  1115.                         begin
  1116.                         Dec(bitNum);
  1117.                         end;
  1118.                     end;
  1119.                 end;
  1120.             if byteNum = PAGESIZE then
  1121.                 begin
  1122.                 done := TRUE;
  1123.                 end
  1124.             else
  1125.                 begin
  1126.                 Inc(byteNum);
  1127.                 end;
  1128.             end;
  1129.         Inc(prNum);
  1130.         byteNum := 1;
  1131.         if PageExists(fName,fId,prNum) then       (* if not past last record *)
  1132.             begin
  1133.             FetchPage(fName,fId,prNum,page);          (* get next b m record *)
  1134.             if BTreeErrorOccurred then Exit;
  1135.             end
  1136.         else
  1137.             begin
  1138.             FillChar(page,PAGESIZE,0);              (* create new record page
  1139.                                                      for this bit map record *)
  1140.             StorePage(fName,fId,prNum,page);           (* store the new page *)
  1141.             if BTreeErrorOccurred then Exit;
  1142.             lastBMRec := prNum;                (* update value of lastBMRec *)
  1143.             end;
  1144.         end;
  1145.     end;                             (* end of FindNextAvailInBitmap routine *)
  1146.  
  1147.  
  1148. (* This routine will set the bit associated with rNum in the file fName to
  1149.    the desired value. It will calculate the correct bitmap record and read it
  1150.    in, set the bit to the value specified by bit (the parameter of type
  1151.    BitValue passed in) and store the bitmap record.                          *)
  1152.  
  1153. procedure SetBitInBitmap(fName : FnString;
  1154.                          var fId : File;               (* var for speed only *)
  1155.                          firstBMRec : PrNumber;
  1156.                          rNum : RecordNumber;
  1157.                          bit : BitValue);
  1158.  
  1159. var
  1160.     page : SinglePage;
  1161.     prNum : PrNumber;
  1162.     byteNum : PageRange;
  1163.     bitNum : BytePosition;
  1164.  
  1165.     begin
  1166.     CalculateBitmapBitLocation(firstBMRec,rNum,prNum,byteNum,bitNum);
  1167.     FetchPage(fName,fId,prNum,page);
  1168.     if BTreeErrorOccurred then Exit;
  1169.     SetBit(page[byteNum],bitNum,bit);
  1170.     StorePage(fName,fId,prNum,page);
  1171.     if BTreeErrorOccurred then Exit;
  1172.     end;                                    (* end of SetBitInBitmap routine *)
  1173.  
  1174. (* This routine will check to see if the bit associated with rNum in the file
  1175.    fName is set or not.  The routine will return TRUE if the bit is set.     *)
  1176.  
  1177. function CheckBitInBitmap(fName : FnString;
  1178.                           var fId : File;              (* var for speed only *)
  1179.                           firstBMRec : PrNumber;
  1180.                           rNum : RecordNumber) : Boolean;
  1181.  
  1182. var
  1183.     page : SinglePage;
  1184.     prNum : PrNumber;
  1185.     byteNum : PageRange;
  1186.     bitNum : BytePosition;
  1187.  
  1188.     begin
  1189.     CalculateBitmapBitLocation(firstBMRec,rNum,prNum,byteNum,bitNum);
  1190.     FetchPage(fName,fId,prNum,page);
  1191.     if BTreeErrorOccurred then Exit;
  1192.     CheckBitInBitmap := BitOn(page[byteNum],bitNum);
  1193.     end;                                    (* end of SetBitInBitmap routine *)
  1194.  
  1195.  
  1196. procedure SetBTreeError(errorCode : IOErrorCode);
  1197.  
  1198.     begin
  1199.     bTreeErrorCode := errorCode;
  1200.     end;
  1201.  
  1202. function GetBTreeError : IOErrorCode;
  1203.  
  1204.     begin
  1205.     GetBTreeError := bTreeErrorCode;
  1206.     end;
  1207.  
  1208.  
  1209. function BTreeErrorOccurred : Boolean;
  1210.  
  1211.     begin
  1212.     BTreeErrorOccurred := bTreeErrorCode <> 0;
  1213.     end;
  1214.  
  1215.  
  1216. begin
  1217. bTreeErrorCode := NOERROR;
  1218. clock.msLongInt := 0;
  1219. clock.lsLongInt := 0;
  1220. end.                                                     (* end of Time unit *)
  1221.  
  1222.